package de.htw.praxisprojekt.algo.impl;

import java.awt.Color;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import de.htw.praxisprojekt.AlgoData;
import de.htw.praxisprojekt.Vector2D;
import de.htw.praxisprojekt.algo.LineAlgorithm;
import de.htw.praxisprojekt.data.AlgoPoint;
import de.htw.praxisprojekt.data.draw.DrawLine;
import de.htw.praxisprojekt.data.draw.DrawObject;

public class ReumannAlgorithm extends LineAlgorithm{

	private JSpinner epsilonValue;

	@Override
	public String getAlgoName(){
		return "Reumann und Witkam";
	}

	@Override
	public JPanel getOptionPane(){
		JPanel panel=super.getOptionPane();
		panel.add(new JLabel("Toleranzweite"));
		panel.add(epsilonValue=new JSpinner(new SpinnerNumberModel(50.0,0.0,1000,1)));
		addChangeListenerToSpinner(epsilonValue);

		panel.add(new JLabel());
		panel.add(new JLabel());

		panel.add(new JLabel());
		panel.add(new JLabel());

		panel.add(new JLabel());
		panel.add(new JLabel());

		return panel;
	}

	public void play(AlgoData algoData,int maxStepIndex){
		super.play(algoData,maxStepIndex);
		List<AlgoPoint> algoPoints=algoData.getAlgoPoints();
		List<DrawObject> drawObjects=algoData.getDrawObjects();
		int stepIndex=0;
		int activeIndex=0;
		int nextIndex=1;
		int p3Index=1;
		int p4Index=2;
		boolean pol1,pol2;
		float epsilon=((Double)epsilonValue.getValue()).floatValue()*algoData.getScaleFactor();
		while(nextIndex<=algoPoints.size()-1&&stepIndex<maxStepIndex){
			pol1=false;
			pol2=false;
			Vector2D p1=algoPoints.get(activeIndex).getPoint();
			Vector2D p2=algoPoints.get(nextIndex).getPoint();
			float[] parallelLine1=Vector2D.getParallelLineCoord(p1.x,p1.y,p2.x,p2.y,epsilon);

			Vector2D pp1=new Vector2D(parallelLine1[0],parallelLine1[1]);
			Vector2D pp2=new Vector2D(parallelLine1[2],parallelLine1[3]);
			float[] parallelLine2=Vector2D.getParallelLineCoord(p1.x,p1.y,p2.x,p2.y,-epsilon);

			Vector2D pp3=new Vector2D(parallelLine2[0],parallelLine2[1]);
			Vector2D pp4=new Vector2D(parallelLine2[2],parallelLine2[3]);

			p3Index=nextIndex;
			p4Index=nextIndex+1;

			while(p4Index<algoPoints.size()&&pol1!=true&&pol2!=true){
				Vector2D p3=algoPoints.get(p3Index).getPoint();
				Vector2D p4=algoPoints.get(p4Index).getPoint();
				Vector2D pi1=Vector2D.getIntersectionPoint(pp1,pp2,p3,p4,epsilon);
				if(pi1.x==0&&pi1.y==0){
					p3Index=p4Index;
					p4Index++;
				}
				pol1=Vector2D.pointOnLine(pi1,p3,p4);
				if(pol1==true){
					drawObjects.add(new DrawLine(p1,p3));
					activeIndex=p3Index;
					nextIndex=activeIndex+1;
					pp2=pi1;
				}
				Vector2D pi2=Vector2D.getIntersectionPoint(pp3,pp4,p3,p4,-epsilon);
				if(pi2.x==0&&pi2.y==0){
					p3Index=p4Index;
					p4Index++;
				}
				pol2=Vector2D.pointOnLine(pi2,p3,p4);
				if(pol2==true){
					drawObjects.add(new DrawLine(p1,p3));
					activeIndex=p3Index;
					nextIndex=activeIndex+1;
					pp4=pi2;
				}else{
					p3Index=p4Index;
					p4Index++;
				}

			}
			if(pol1==true||pol2==true){
				if(stepIndex==maxStepIndex-1){
					drawObjects.add(new DrawLine(new Vector2D(pp1),new Vector2D(pp2)).setColor(Color.BLUE));
					drawObjects.add(new DrawLine(new Vector2D(pp3),new Vector2D(pp4)).setColor(Color.BLUE));
				}
				stepIndex++;
			}else{
				nextIndex=algoPoints.size()-1;
				p2=algoPoints.get(nextIndex).getPoint();
				drawObjects.add(new DrawLine(p1,p2));
				activeIndex=nextIndex;
				nextIndex++;
			}
		}
		setStepIndex(stepIndex);
	}
}